package interface_JDK_0918.cloneable;

import com.sun.org.apache.bcel.internal.generic.ATHROW;

/**
 * java.Cloneable接口
 * 当一个类实现Cloneable接口，这个类就具备了可被“克隆”的能力
 * 克隆羊多利，就是对象B是根据对象A复制而来的，这个复制不是简单的创建了两个引用向同一个对象
 * 而是确实产生了两个独立对象，对象B的所有属性和行为都是完全从A对象复制过来的
 *
 * Cloneable:没有任何抽象方法，称为标记接口，不可省略
 * JVM只会识别所有带这个Cloneable接口的子类，打上可复制的标记
 * Serializable也是标记接口
 *
 * public interface Cloneable{
 * }
 *深浅拷贝：
 * 浅拷贝：对象内部包含其他类对象，浅拷贝只会复制其他类的地址，不会产生新的对象
 * 深拷贝：对象内部包含其他类对象，深拷贝会产生新的对象（无需掌握实现）
 * 深拷贝的实现：
 * 递归调用：将所有内部包含的其他对象都继承Cloneable接口，重写clone()方法
 * 序列化调用：就是将任何对象变为字符串的过程（json字符串）
 * 反序列化：还原原来对象的过程称之为反序列化
 */
class  Money{
    double money=100.5;
}

public class Person implements Cloneable{

    private String name;
    private int age;
    Money sal=new Money();//产生一个Money类对象
    public Person clone(){
        //抛出异常
        Person person=null;
        try {
            // Object类的clone方法，所有对象都有，但是只有实现了Cloneable接口的子类才能真正使用
            person = (Person) super.clone();
        }catch(CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
        return person;
    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public void show(){
        System.out.println("名字："+this.name+"  年龄:"+this.age+" Money对象"+this.sal);
    }

    public static void main(String[] args) {
        Person person=new Person("小乖",19);
        Person person1=person;//引用复制
        Person person2=person.clone();
        System.out.println(person);
        System.out.println(person1);//地址一样
        System.out.println(person2);//地址不一样，属性一样，克隆而来
        person.show();
        person1.show();//Money对象地址一样，引用复制
        person2.show();//Money对象地址一样，浅拷贝，克隆
    }
}
